url.as_slice().to_url().map_err(human)
}
- /// Translates the HTTP url of the registry to the git URL
- fn git_url(&self) -> Url {
- let mut url = self.source_id.get_url().clone();
- url.path_mut().unwrap().push("git".to_string());
- url.path_mut().unwrap().push("index".to_string());
- url
- }
-
/// Decode the configuration stored within the registry.
///
/// This requires that the index has been at least checked out.
try!(fs::mkdir_recursive(&self.checkout_path, io::UserDir));
let _ = fs::rmdir_recursive(&self.checkout_path);
- let url = self.git_url().to_string();
+ let url = self.source_id.get_url().to_string();
let repo = try!(git2::Repository::init(&self.checkout_path));
Ok(repo)
}
/// then ready for inspection.
///
/// No action is taken if the package is already downloaded.
- fn download_package(&mut self, pkg: &PackageId, url: Url)
+ fn download_package(&mut self, pkg: &PackageId, url: &Url)
-> CargoResult<Path> {
let dst = self.cache_path.join(url.path().unwrap().last().unwrap()
.as_slice());
};
// TODO: don't download into memory
let resp = try!(handle.get(url.to_string()).exec());
- if resp.get_code() != 200 {
+ if resp.get_code() != 200 && resp.get_code() != 0 {
return Err(internal(format!("Failed to get 200 reponse from {}\n{}",
url, resp)))
}
let repo = try!(self.open());
// git fetch origin
- let url = self.git_url().to_string();
+ let url = self.source_id.get_url().to_string();
let refspec = "refs/heads/*:refs/remotes/origin/*";
let mut remote = try!(repo.remote_create_anonymous(url.as_slice(),
refspec));
url.path_mut().unwrap().push(format!("{}-{}.tar.gz",
package.get_name(),
package.get_version()));
- let path = try!(self.download_package(package, url).chain_error(|| {
- internal(format!("Failed to download package `{}`", package))
+ let path = try!(self.download_package(package, &url).chain_error(|| {
+ internal(format!("Failed to download package `{}` from {}",
+ package, url))
}));
let path = try!(self.unpack_package(package, path).chain_error(|| {
internal(format!("Failed to unpack package `{}`", package))
--- /dev/null
+use std::io::{mod, fs, File};
+use url::Url;
+use git2;
+use serialize::hex::ToHex;
+
+use support::{ResultTest, project, execs, cargo_dir};
+use support::{UPDATING, DOWNLOADING, COMPILING};
+use support::paths;
+use cargo::util::Sha256;
+
+use hamcrest::assert_that;
+
+fn registry_path() -> Path { paths::root().join("registry") }
+fn registry() -> Url { Url::from_file_path(®istry_path()).unwrap() }
+fn dl_path() -> Path { paths::root().join("dl") }
+fn dl_url() -> Url { Url::from_file_path(&dl_path()).unwrap() }
+
+fn cksum(s: &[u8]) -> String {
+ let mut sha = Sha256::new();
+ sha.update(s);
+ sha.final().to_hex()
+}
+
+fn setup() {
+ let config = paths::root().join(".cargo/config");
+ fs::mkdir_recursive(&config.dir_path(), io::UserDir).assert();
+ File::create(&config).write_str(format!(r#"
+ [registry]
+ host = "{reg}"
+ token = "api-token"
+ "#, reg = registry()).as_slice()).assert();
+
+ fs::mkdir(®istry_path(), io::UserDir).assert();
+
+ // Init a new registry
+ let repo = git2::Repository::init(®istry_path()).unwrap();
+ let mut config = repo.config().unwrap();
+ config.set_str("user.name", "name").unwrap();
+ config.set_str("user.email", "email").unwrap();
+ let mut index = repo.index().unwrap();
+
+ // Prepare the "to download" artifacts
+ let foo = include_bin!("fixtures/foo-0.0.1.tar.gz");
+ let bar = include_bin!("fixtures/bar-0.0.1.tar.gz");
+ let notyet = include_bin!("fixtures/notyet-0.0.1.tar.gz");
+ let foo_cksum = dl("pkg/foo/foo-0.0.1.tar.gz", foo);
+ let bar_cksum = dl("pkg/bar/bar-0.0.1.tar.gz", bar);
+ dl("pkg/bad-cksum/bad-cksum-0.0.1.tar.gz", foo);
+ let notyet = dl("pkg/notyet/notyet-0.0.1.tar.gz", notyet);
+
+ // Prepare the registry's git repo
+ file(&mut index, "config.json", format!(r#"
+ {{"dl_url":"{}"}}
+ "#, dl_url()).as_slice());
+ file(&mut index, "fo/oX/foo",
+ format!(r#"{{"name":"foo","vers":"0.0.1","deps":[],"cksum":"{}"}}"#,
+ foo_cksum).as_slice());
+ file(&mut index, "ba/rX/bar",
+ format!(r#"{{"name":"bar","vers":"0.0.1","deps":["foo|>=0.0.0"],"cksum":"{}"}}"#,
+ bar_cksum).as_slice());
+ file(&mut index, "ba/d-/bad-cksum",
+ format!(r#"{{"name":"bad-cksum","vers":"0.0.1","deps":[],"cksum":"{}"}}"#,
+ bar_cksum).as_slice());
+ file(&mut index, "no/ty/notyet",
+ format!(r#"{{"name":"notyet","vers":"0.0.1","deps":[],"cksum":"{}"}}"#,
+ notyet).as_slice());
+ index.remove_path(&Path::new("no/ty/notyet")).unwrap();
+
+ // Commit!
+ index.write().unwrap();
+ let id = index.write_tree().unwrap();
+ let tree = git2::Tree::lookup(&repo, id).unwrap();
+ let sig = git2::Signature::default(&repo).unwrap();
+ git2::Commit::new(&repo, Some("HEAD"), &sig, &sig,
+ "Initial commit", &tree, []).unwrap();
+
+ fn file(index: &mut git2::Index, path: &str, contents: &str) {
+ let dst = index.path().unwrap().dir_path().dir_path().join(path);
+ fs::mkdir_recursive(&dst.dir_path(), io::UserDir).assert();
+ File::create(&dst).write_str(contents).unwrap();
+ index.add_path(&Path::new(path)).unwrap();
+ }
+
+ fn dl(path: &str, contents: &[u8]) -> String {
+ let dst = dl_path().join(path);
+ fs::mkdir_recursive(&dst.dir_path(), io::UserDir).assert();
+ File::create(&dst).write(contents).unwrap();
+ cksum(contents)
+ }
+}
+
+test!(simple {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ foo = ">= 0.0.0"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0).with_stdout(format!("\
+{updating} registry `{reg}`
+{downloading} foo v0.0.1 (the package registry)
+{compiling} foo v0.0.1 (the package registry)
+{compiling} foo v0.0.1 ({dir})
+",
+ updating = UPDATING,
+ downloading = DOWNLOADING,
+ compiling = COMPILING,
+ dir = p.url(),
+ reg = registry()).as_slice()));
+})
+
+test!(deps {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ bar = ">= 0.0.0"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(0).with_stdout(format!("\
+{updating} registry `{reg}`
+{downloading} [..] v0.0.1 (the package registry)
+{downloading} [..] v0.0.1 (the package registry)
+{compiling} foo v0.0.1 (the package registry)
+{compiling} bar v0.0.1 (the package registry)
+{compiling} foo v0.0.1 ({dir})
+",
+ updating = UPDATING,
+ downloading = DOWNLOADING,
+ compiling = COMPILING,
+ dir = p.url(),
+ reg = registry()).as_slice()));
+})
+
+test!(nonexistent {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ nonexistent = ">= 0.0.0"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(101).with_stderr("\
+No package named `nonexistent` found (required by `foo`).
+Location searched: the package registry
+Version required: >= 0.0.0
+"));
+})
+
+test!(bad_cksum {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ bad-cksum = ">= 0.0.0"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+
+ assert_that(p.cargo_process("build").arg("-v"),
+ execs().with_status(101).with_stderr("\
+Unable to get packages from source
+
+Caused by:
+ Failed to download package `bad-cksum v0.0.1 (the package registry)` from [..]
+
+Caused by:
+ Failed to verify the checksum of `bad-cksum v0.0.1 (the package registry)`
+"));
+})
+
+test!(update_registry {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ notyet = ">= 0.0.0"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+
+ assert_that(p.cargo_process("build"),
+ execs().with_status(101).with_stderr("\
+No package named `notyet` found (required by `foo`).
+Location searched: the package registry
+Version required: >= 0.0.0
+"));
+
+ // Add the package and commit
+ let repo = git2::Repository::open(®istry_path()).unwrap();
+ let mut index = repo.index().unwrap();
+ index.add_path(&Path::new("no/ty/notyet")).unwrap();
+ let id = index.write_tree().unwrap();
+ let tree = git2::Tree::lookup(&repo, id).unwrap();
+ let sig = git2::Signature::default(&repo).unwrap();
+ let parent = git2::Reference::name_to_id(&repo, "refs/heads/master").unwrap();
+ let parent = git2::Commit::lookup(&repo, parent).unwrap();
+ git2::Commit::new(&repo, Some("HEAD"), &sig, &sig,
+ "Another commit", &tree,
+ [&parent]).unwrap();
+
+ assert_that(p.process(cargo_dir().join("cargo")).arg("build"),
+ execs().with_status(0).with_stdout(format!("\
+{updating} registry `{reg}`
+{downloading} notyet v0.0.1 (the package registry)
+{compiling} notyet v0.0.1 (the package registry)
+{compiling} foo v0.0.1 ({dir})
+",
+ updating = UPDATING,
+ downloading = DOWNLOADING,
+ compiling = COMPILING,
+ dir = p.url(),
+ reg = registry()).as_slice()));
+})